home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume10 / logo / part02 < prev    next >
Encoding:
Internet Message Format  |  1987-06-23  |  54.7 KB

  1. Path: uunet!rs
  2. From: rs@uunet.UU.NET (Rich Salz)
  3. Newsgroups: comp.sources.unix
  4. Subject: v10i022: Logo interpreter for Unix, Part02/06
  5. Message-ID: <448@uunet.UU.NET>
  6. Date: 24 Jun 87 20:21:38 GMT
  7. Organization: UUNET Communications Services, Arlington, VA
  8. Lines: 2292
  9. Approved: rs@uunet.uu.net
  10.  
  11. Submitted by: Brian Harvey <bh@mit-amt>
  12. Mod.Sources: Volume 10, Number 22
  13. Archive-Name: logo/Part02
  14.  
  15. #! /bin/sh
  16. # This is a shell archive.  Remove anything before this line, then unpack
  17. # it by saving it into a file and typing "sh file".  To overwrite existing
  18. # files, type "sh file -c".  You can also feed this as standard input via
  19. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  20. # will see the following message at the end:
  21. #        "End of archive 2 (of 6)."
  22. # Contents:  applediff logo.h logonum.c logoparse.c olddiff procedit.c
  23. #   procvars.c storage.c
  24. # Wrapped by rsalz@pineapple.bbn.com on Wed Jun 24 14:26:54 1987
  25. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  26. if test -f applediff -a "${1}" != "-c" ; then 
  27.   echo shar: Will not over-write existing file \"applediff\"
  28. else
  29. echo shar: Extracting \"applediff\" \(4650 characters\)
  30. sed "s/^X//" >applediff <<'END_OF_applediff'
  31. X
  32. XA Guide to LSRHS Logo for people who know Apple Logo
  33. X
  34. XAlthough the two versions of Logo are very different internally, they
  35. Xare fairly similar in the way you use them.  This guide assumes that
  36. Xyou know all about Apple Logo, and explains the differences.  There are
  37. Xenough differences that you can't just run your Apple Logo programs
  38. Xunchanged, but what you know of Apple Logo will help you understand
  39. XLSRHS Logo.  Read this along with the LSRHS Logo Manual.
  40. X
  41. X1.  Multi-instruction lines.  If you put more than one Logo instruction on
  42. Xa line, you may use a semicolon between instructions for better readability:
  43. X        print "foo; print "baz
  44. X
  45. X2.  Comments can be used, starting with exclamation point:
  46. X        print "foo ! This is a comment
  47. X
  48. X3.  There is no built-in procedure editor; your favorite text editor is run
  49. Xin a separate process instead.  There is no edns primitive.
  50. X
  51. X4.  Differences in graphics:  LSRHS doesn't have background, dot,
  52. Xfence, pen, setbg, setpen, window, or wrap.  Instead of pencolor and
  53. Xsetpc, there are somewhat different primitives setcolor and pencolor.  There
  54. Xis also setxy, which is like setpos but takes two scalar inputs instead
  55. Xof one vector.  Similarly, towardsxy takes two scalar inputs.  (Library
  56. Xprocedures setpos and towards are provided.)
  57. X
  58. X5.  Differences in words and lists:  In addition to the Apple Logo primitives,
  59. XLSRHS Logo has sentencep (true only if the input is a list of words, not a
  60. Xlist of lists); is (like equalp, but true for numbers only if they are string
  61. Xequal, so "is 3.0 3" outputs false); memberp and item for words as well as
  62. Xlists.
  63. X
  64. X6.  Differences in use of variables:  LSRHS local takes only one input.
  65. XThere is no name, only make.
  66. X
  67. X7.  Differences in arithmetic operations: There is no rerandom.  Quotient
  68. Xand / are equivalent.  Additional arithmetic operations are difference
  69. X(prefix -), greaterp (prefix >), lessp (prefix <), maximum, minimum, zerop,
  70. Xpow (two inputs, x to the y power).
  71. X
  72. X8.  Differences in conditionals and flow of control: LSRHS Logo has trace
  73. X(with no input, traces all procedures; can take a LIST of procedure names to
  74. Xtrace only those) and untrace (no inputs, affects all procedures).  Pausing
  75. Xworks somewhat differently.  Your Unix interrupt character pauses; your quit
  76. Xcharacter stops all procedures.  The equivalent of ERRACT is the procedure
  77. Xerrpause.  See the manual.
  78. X
  79. X9.  Differences in reading and printing:  There is no buttonp or paddle.
  80. XIn order to use readchar and keyp, you must first use cbreak.  (See the
  81. XLSRHS Logo Manual.)  Apple show is called fprint in LSRHS.  There is also
  82. Xftype for full type without newline.
  83. X
  84. X10.  Differences in screen commands:  LSRHS Logo cleartext clears the
  85. Xentire screen.  There is no 'cursor' operation.  Setcursor is a library
  86. Xprocedure using the primitive setcursorxy with two scalar inputs.
  87. X
  88. X11.  Workspace management:  There is no concept of a workspace in LSRHS
  89. XLogo.  Procedures are saved in individual files, and variables are not
  90. Xsaved at all.  Therefore, none of bury, erall, ern, erns, erps, package,
  91. Xpkgall, poall, pons, pops, or unbury exist.  The Apple Logo po is called
  92. Xshow (note that Apple Logo uses show with a different meaning), but po
  93. Xis accepted as an abbreviation.  Erase exists, and pots exists with no input.
  94. X
  95. X12.  Differences in files:  None of catalog, disk, erasefile, load,
  96. Xsave, and setdisk exist in LSRHS Logo.  But there is a facility for
  97. Xreading and writing arbitrary text files, using the primitives
  98. Xopenread, openwrite, fileread, fileword, fileprint, filefprint, filetype,
  99. Xfileftype, and close.  See the LSRHS Logo Manual.  Other file directory
  100. Xmanipulation can be done using the unix command:
  101. X        unix [ls -la]
  102. X
  103. X13.  Error handling:  The primitives catch, throw, and error do not
  104. Xexist in LSRHS Logo.  The special name erract is not used.
  105. XThere is a command toplevel which is equivalent to throw "toplevel.
  106. X
  107. X14.  Procedure redefinition:  None of copydef, define, definedp,
  108. Xprimitivep, or text exist.  The special name redefp is not used.
  109. X
  110. X15.  Miscellany:  There are no label, nodes, recycle, reparse, .bpt,
  111. X.contents, .deposit, .examine, or .printer primitives.  The go primitive
  112. Xtakes a numeric input; a procedure line can start with a number which is
  113. Xignored except to serve as a label for go.  The LSRHS time primitive
  114. Xoutputs the current date and time.  The command goodbye is used to exit
  115. Xfrom Logo.  The command help prints a help message, and describe with
  116. Xone input, the name of a primitive, prints a description of that
  117. Xprimitive.
  118. X
  119. X16.  Floor turtles:  LSRHS has the primitives turtle, hitoot, lotoot,
  120. Xlampon, lampoff, ftouch, btouch, ltouch, and rtouch applicable to
  121. Xfloor turtles.
  122. X
  123. END_OF_applediff
  124. if test 4650 -ne `wc -c <applediff`; then
  125.     echo shar: \"applediff\" unpacked with wrong size!
  126. fi
  127. # end of overwriting check
  128. fi
  129. if test -f logo.h -a "${1}" != "-c" ; then 
  130.   echo shar: Will not over-write existing file \"logo.h\"
  131. else
  132. echo shar: Extracting \"logo.h\" \(5336 characters\)
  133. sed "s/^X//" >logo.h <<'END_OF_logo.h'
  134. X
  135. X/* Unix Logo, release 3 */
  136. X
  137. X/* Installation-dependent parameters */
  138. X
  139. X#define EDT "/u/bh/bin/jove"    /* default editor for procedure editing */
  140. X
  141. X/* Turn on the graphics devices you have. */
  142. X/* #define ATARI /* L-S and Atari */
  143. X#define GIGI /* L-S */
  144. X/* #define ADM /* COM */
  145. X/* #define TEK /* COM */
  146. X/* #define SUN /* Lucasfilm */
  147. X/* #define FLOOR /* L-S */
  148. X/* #define NOTURTLE /* turn on for no graphics at all */
  149. X
  150. X/* #define EUNICE        /* turn on for inferior Eunice */
  151. X
  152. X/* #define SMALL         /* turn on for non-split-I/D PDP-11. */
  153. X
  154. X/* #define EXTLOGO        /* Turn on for .logo instead of .lg */
  155. X
  156. X#ifdef SMALL
  157. X#define NAMELEN 11
  158. X#else
  159. X#define NAMELEN 100        /* max length of procedure name, must fit
  160. X                   into xxxxxxx.lg filename format */
  161. X    /* Should be 11 for pre-4.2 Unix unless EXTLOGO is on,
  162. X       9 for Eunice or EXTLOGO. */
  163. X#endif SMALL
  164. X
  165. X/* Initial values for which signal pauses and which aborts */
  166. X#define PAUSESIG SIGINT
  167. X#define OTHERSIG SIGQUIT
  168. X
  169. X/* Following for 4.2BSD */
  170. X#define RAND random
  171. X#define SRAND srandom
  172. X
  173. X/* Following for non-4.2
  174. X#define RAND rand
  175. X#define SRAND srand
  176. X */
  177. X
  178. X#ifdef SMALL
  179. X#define MAXALLOC 30
  180. X#define YYMAXDEPTH 150
  181. X#else
  182. X
  183. X/* Memory allocation tuning.  Adjust these numbers if you run out of space. */
  184. X#define MAXALLOC 100
  185. X/* Increase MAXALLOC for "I can't remember everything you have told me." */
  186. X#define YYMAXDEPTH 2200
  187. X/* Increase YYMAXDEPTH if you see "Too many levels of recursion." */
  188. X/* Decrease something if you see "No more memory, sorry." */
  189. X#endif
  190. X
  191. X#ifndef SMALL
  192. X#define DEBUG        /* enable debugging code */
  193. X#define PAUSE        /* enable pause feature */
  194. X#define SETCURSOR    /* enable termcap stuff */
  195. X#endif
  196. X
  197. X#define LIBLOGO "/usr/lib/logo/"
  198. X#define LIBNL "cat /usr/lib/logo/nl >> %s"
  199. X#define HELPFILE "/usr/doc/logo/helpfile"
  200. X#define DOCLOGO "/usr/doc/logo/"
  201. X
  202. X#ifdef EXTLOGO
  203. X#define EXTEN ".logo"
  204. X#define POTSCMD "/usr/lib/logo/logohead *.logo"
  205. X#else
  206. X#define EXTEN ".lg"
  207. X#define POTSCMD "/usr/lib/logo/logohead *.lg"
  208. X#endif
  209. X
  210. X/* ---------  End of installation-dependent parameters  --------- */
  211. X
  212. X#ifdef SMALL
  213. X#define NUMBER float
  214. X#define FIXNUM int
  215. X#define EFMT "%e"
  216. X#define FIXFMT "%d"
  217. X#define IBUFSIZ 200
  218. X#define PSTKSIZ 64
  219. X#else
  220. X#define NUMBER double
  221. X#define FIXNUM long
  222. X#define EFMT "%E"
  223. X#define FIXFMT "%D"
  224. X#define IBUFSIZ 1000
  225. X#define PSTKSIZ 128
  226. X#endif
  227. X
  228. X#ifdef DEBUG
  229. X#define YYDEBUG
  230. X#define JFREE jfree
  231. X#else
  232. X#define JFREE free
  233. X#endif
  234. X
  235. X#define GLOBAL extern
  236. X#define READ 0
  237. X#define WRITE 1
  238. X#define NULL 0
  239. X#define FAST register
  240. X#define FOREVER for(;;)
  241. X#define FILDES int
  242. X#define BUFSIZE 512
  243. X#include <stdio.h>
  244. X#undef getchar
  245. X
  246. Xstruct cons {
  247. X    struct object *car;
  248. X    struct object *cdr;
  249. X};
  250. X
  251. Xstruct object {
  252. X#ifdef SMALL
  253. X    char obtype;
  254. X    char refcnt;
  255. X#else
  256. X    int obtype;
  257. X    int refcnt;
  258. X#endif
  259. X    union {
  260. X        struct cons ob_cons;
  261. X        char *ob_str;
  262. X        FIXNUM ob_int;
  263. X        NUMBER ob_dub;
  264. X    } obob;
  265. X};
  266. X
  267. X#define obcons    obob.ob_cons
  268. X#define obstr    obob.ob_str
  269. X#define obint    obob.ob_int
  270. X#define obdub    obob.ob_dub
  271. X#define obcar    obob.ob_cons.car
  272. X#define obcdr    obob.ob_cons.cdr
  273. X
  274. X#define CONS    0
  275. X#define STRING    1
  276. X#define    INT    2
  277. X#define    DUB    3
  278. X
  279. Xextern int memtrace;
  280. X
  281. X#define listp(x)    (((x)==0) || (((x)->obtype)==CONS))
  282. X#define stringp(x)    ((x) && (((x)->obtype)==STRING))
  283. X#define intp(x)        ((x) && (((x)->obtype)==INT))
  284. X#define dubp(x)        ((x) && (((x)->obtype)==DUB))
  285. X
  286. Xextern char *ckmalloc();
  287. Xextern struct object *localize(),*globcopy(),*globcons(),*loccons();
  288. Xextern struct object *objstr(),*objcpstr(),*objint(),*objdub();
  289. Xextern struct object *numconv(),*dubconv(),*true(),*false();
  290. Xextern struct object *makelist(),*stringform(),*torf();
  291. Xextern int errrec();
  292. X
  293. Xstruct stkframe
  294. X{
  295. X    struct alist *loclist;
  296. X    char argtord;
  297. X    char iftest;
  298. X    int *stk;
  299. X    int ind;
  300. X    int *oldnewstk;
  301. X    struct alist *oldnloc;
  302. X    struct plist *prevpcell;
  303. X    int oldyyc;
  304. X    int oldyyl;
  305. X    char *oldbpt;
  306. X    struct stkframe *prevframe;
  307. X#ifdef SMALL
  308. X    char oldline;
  309. X    char oldpfg;
  310. X#else
  311. X    int oldline;
  312. X    int oldpfg;
  313. X#endif
  314. X};
  315. X
  316. Xstruct plist
  317. X{
  318. X    struct plist *before;
  319. X    struct object *procname;
  320. X    int recdepth;
  321. X    struct object *ptitle;
  322. X    int *realbase;
  323. X    struct lincell *plines;
  324. X    struct plist *after;
  325. X};
  326. X
  327. Xstruct lincell
  328. X{
  329. X    int linenum;
  330. X    int *base;
  331. X    int index;
  332. X    struct lincell *nextline;
  333. X};
  334. X
  335. Xstruct alist
  336. X{
  337. X    struct object *name;
  338. X    struct object *val;
  339. X    struct alist *next;
  340. X};
  341. X
  342. Xstruct lexstruct
  343. X{
  344. X    char *word;
  345. X    int lexret;
  346. X    struct object *(*lexval)();
  347. X    char *abbr;
  348. X};
  349. X
  350. Xstruct runblock
  351. X{
  352. X    struct runblock *rprev;
  353. X    struct object *str;
  354. X    char *svbpt;
  355. X    int roldyyc;
  356. X    int roldyyl;
  357. X    int roldline;
  358. X    FIXNUM rcount;
  359. X    FIXNUM rupcount;
  360. X    int svpflag;
  361. X    int svletflag;
  362. X    char svch;
  363. X};
  364. X
  365. Xstruct display {
  366. X    NUMBER turtx,turty,turth;    /* current values */
  367. X    NUMBER xlow,xhigh,ylow,yhigh;    /* limits for this dpy */
  368. X    NUMBER stdscrunch;        /* standard aspect ratio */
  369. X    int cleared;            /* nonzero after first use */
  370. X    char *init,*finish;        /* printed to enable, disable gfx */
  371. X    char *totext;            /* printed for temporary textscreen */
  372. X    char *clear;            /* printed for cs, and after init */
  373. X    int (*drawturt)();        /* one arg, 0 to show, 1 to erase */
  374. X    int (*drawfrom)(), (*drawto)();    /* 2 args, x and y, draw vector */
  375. X    int (*txtchk)();        /* make error if can't gfx in txtmode */
  376. X    int (*infn)(), (*outfn)();    /* no args, called to enable, disable */
  377. X    int (*turnturt)();        /* no args, tell Atari turtle heading */
  378. X    int (*penc)(), (*setc)();    /* color map routines */
  379. X    int (*state)();            /* one arg, state change flag */
  380. X};
  381. X
  382. Xextern int nullfn();
  383. X
  384. END_OF_logo.h
  385. if test 5336 -ne `wc -c <logo.h`; then
  386.     echo shar: \"logo.h\" unpacked with wrong size!
  387. fi
  388. # end of overwriting check
  389. fi
  390. if test -f logonum.c -a "${1}" != "-c" ; then 
  391.   echo shar: Will not over-write existing file \"logonum.c\"
  392. else
  393. echo shar: Extracting \"logonum.c\" \(9811 characters\)
  394. sed "s/^X//" >logonum.c <<'END_OF_logonum.c'
  395. X
  396. X/*    Numeric operations in LOGO.
  397. X *    In arithmetic operations, the input, which is a character, is
  398. X *    converted to numeric, the operations are done, and the result is
  399. X *    converted back to character.
  400. X *    In all cases, the inputs are freed, and a new output is created.
  401. X *
  402. X *    Copyright (C) 1979, The Children's Museum, Boston, Mass.
  403. X *    Written by Douglas B. Klunder.
  404. X */
  405. X
  406. X#include <math.h>
  407. X#include "logo.h"
  408. X
  409. Xnump(x)        /* non-LOGO numberp, just for strings */
  410. Xregister struct object *x;
  411. X{    /* a number is a series of at least one digit, with an optional
  412. X    * starting + or -. */
  413. X    register char ch,*cp;
  414. X
  415. X    cp = x->obstr;
  416. X    if (*cp=='\0') return(0);
  417. X    if (*cp!='-' && *cp!='+' && (*cp<'0' || *cp>'9') && *cp!='.') return(0);
  418. X    if ((*cp=='-' || *cp=='+' || *cp=='.') && *(cp+1)=='\0') return(0);
  419. X    if(*cp=='.' && index(cp+1,'.')) return(0);
  420. X    cp++;
  421. X    while ((ch = *cp)!='\0') {
  422. X        if ((ch<'0'||ch>'9')&&(ch!='e')&&(ch!='E')&&(ch!='.'))
  423. X            return(0);
  424. X        if ((ch == 'e') || (ch == 'E')) {
  425. X            if (index(cp+1,'e') || index(cp+1,'E')
  426. X              || index(cp+1,'.')) return(0);
  427. X            if (((ch = *(cp+1))=='+') || (ch=='-')) cp++;
  428. X        }
  429. X        else if (ch == '.') {
  430. X            if (index(cp+1,'e') || index(cp+1,'E')
  431. X              || index(cp+1,'.')) return(0);
  432. X        }
  433. X        cp++;
  434. X    }
  435. X    return(1);
  436. X}
  437. X
  438. X/* Check a STRING object to see if it's an integer string */
  439. Xisint(x)
  440. Xregister struct object *x;
  441. X{
  442. X    register char ch,*cp;
  443. X
  444. X    cp = x->obstr;
  445. X    while (ch = *cp++)
  446. X        if ((ch == '.') || (ch == 'e') || (ch == 'E'))
  447. X            return(0);
  448. X    return(1);
  449. X}
  450. X
  451. X/* convert object (which might be a word of digits) to a number */
  452. Xstruct object *numconv(thing,op)
  453. Xregister struct object *thing;
  454. Xchar *op;
  455. X{
  456. X    register struct object *newthing;
  457. X    FIXNUM ithing;
  458. X    NUMBER dthing;
  459. X
  460. X    if (thing == 0) ungood(op,thing);
  461. X    switch (thing->obtype) {
  462. X        case CONS:
  463. X            ungood(op,thing);
  464. X        case INT:
  465. X        case DUB:
  466. X            return(thing);
  467. X        default:
  468. X            if (!nump(thing)) ungood(op,thing);
  469. X            if (isint(thing)) {
  470. X                sscanf(thing->obstr,FIXFMT,&ithing);
  471. X                newthing = localize(objint(ithing));
  472. X            } else {
  473. X                sscanf(thing->obstr,EFMT,&dthing);
  474. X                newthing = localize(objdub(dthing));
  475. X            }
  476. X    }
  477. X    mfree(thing);
  478. X    return(newthing);
  479. X}
  480. X
  481. X/* convert integer to double */
  482. Xstruct object *dubconv(num)
  483. Xregister struct object *num;
  484. X{
  485. X    NUMBER d;
  486. X
  487. X    if (dubp(num)) return(num);
  488. X    d = num->obint;
  489. X    mfree(num);
  490. X    return(localize(objdub(d)));
  491. X}
  492. X
  493. Xstruct object *opp(x)    /* Unary - */
  494. Xregister struct object *x;
  495. X{
  496. X    register struct object *ans;
  497. X
  498. X    x = numconv(x,"Minus");
  499. X    if (intp(x)) {
  500. X        ans = objint(-(x->obint));
  501. X    } else {
  502. X        ans = objdub(-(x->obdub));
  503. X    }
  504. X    mfree(x);
  505. X    return(localize(ans));
  506. X}
  507. X
  508. Xstruct object *add(x,y)    /* sum */
  509. Xregister struct object *x,*y;
  510. X{
  511. X    FIXNUM iz;
  512. X    NUMBER dz;
  513. X    register struct object *z;
  514. X
  515. X    x = numconv(x,"Sum");
  516. X    y = numconv(y,"Sum");
  517. X    if (!intp(x) || !intp(y)) {
  518. X        x = dubconv(x);
  519. X        y = dubconv(y);
  520. X    }
  521. X    if (intp(x)) {
  522. X        iz = (x->obint)+(y->obint);
  523. X        z = objint(iz);
  524. X    } else {
  525. X        dz = (x->obdub)+(y->obdub);
  526. X        z = objdub(dz);
  527. X    }
  528. X    mfree(x);
  529. X    mfree(y);
  530. X    return(localize(z));
  531. X}
  532. X
  533. Xstruct object *sub(x,y)    /* difference */
  534. Xregister struct object *x,*y;
  535. X{
  536. X    FIXNUM iz;
  537. X    NUMBER dz;
  538. X    register struct object *z;
  539. X
  540. X    x = numconv(x,"Difference");
  541. X    y = numconv(y,"Difference");
  542. X    if (!intp(x) || !intp(y)) {
  543. X        x = dubconv(x);
  544. X        y = dubconv(y);
  545. X    }
  546. X    if (intp(x)) {
  547. X        iz = (x->obint)-(y->obint);
  548. X        z = objint(iz);
  549. X    } else {
  550. X        dz = (x->obdub)-(y->obdub);
  551. X        z = objdub(dz);
  552. X    }
  553. X    mfree(x);
  554. X    mfree(y);
  555. X    return(localize(z));
  556. X}
  557. X
  558. Xstruct object *mult(x,y)    /* product */
  559. Xregister struct object *x,*y;
  560. X{
  561. X    FIXNUM iz;
  562. X    NUMBER dz;
  563. X    register struct object *z;
  564. X
  565. X    x = numconv(x,"Product");
  566. X    y = numconv(y,"Product");
  567. X    if (!intp(x) || !intp(y)) {
  568. X        x = dubconv(x);
  569. X        y = dubconv(y);
  570. X    }
  571. X    if (intp(x)) {
  572. X        iz = (x->obint)*(y->obint);
  573. X        z = objint(iz);
  574. X    } else {
  575. X        dz = (x->obdub)*(y->obdub);
  576. X        z = objdub(dz);
  577. X    }
  578. X    mfree(x);
  579. X    mfree(y);
  580. X    return(localize(z));
  581. X}
  582. X
  583. Xdivzero(name)
  584. Xchar *name;
  585. X{
  586. X    pf1("%s can't divide by zero.\n",name);
  587. X    errhand();
  588. X}
  589. X
  590. Xstruct object *div(x,y)    /* quotient */
  591. Xregister struct object *x,*y;
  592. X{
  593. X    NUMBER dz;
  594. X
  595. X    x = numconv(x,"Quotient");
  596. X    y = numconv(y,"Quotient");
  597. X    x = dubconv(x);
  598. X    y = dubconv(y);
  599. X    if (y->obdub == 0.0) divzero("Quotient");
  600. X    dz = (x->obdub)/(y->obdub);
  601. X    mfree(x);
  602. X    mfree(y);
  603. X    if (dz == (NUMBER)(FIXNUM)dz) {
  604. X        return(localize(objint((FIXNUM)dz)));
  605. X    } else {
  606. X        return(localize(objdub(dz)));
  607. X    }
  608. X}
  609. X
  610. Xstruct object *rem(x,y)    /* remainder */
  611. Xregister struct object *x,*y;
  612. X{
  613. X    FIXNUM iz;
  614. X    register struct object *z;
  615. X
  616. X    x = numconv(x,"Remainder");
  617. X    y = numconv(y,"Remainder");
  618. X    if (!intp(x)) ungood("Remainder",x);
  619. X    if (!intp(y)) ungood("Remainder",y);
  620. X    if (y->obint == 0) divzero("Remainder");
  621. X    iz = (x->obint)%(y->obint);
  622. X    z = objint(iz);
  623. X    mfree(x);
  624. X    mfree(y);
  625. X    return(localize(z));
  626. X}
  627. X
  628. Xstruct object *torf(pred)
  629. Xint pred;
  630. X{
  631. X    if (pred) return(true());
  632. X    return(false());
  633. X}
  634. X
  635. Xstruct object *greatp(x,y)    /* greaterp */
  636. Xregister struct object *x,*y;
  637. X{
  638. X    int iz;
  639. X
  640. X    x = numconv(x,"Greaterp");
  641. X    y = numconv(y,"Greaterp");
  642. X    if (!intp(x) || !intp(y)) {
  643. X        x = dubconv(x);
  644. X        y = dubconv(y);
  645. X    }
  646. X    if (intp(x)) {
  647. X        iz = ((x->obint)>(y->obint));
  648. X    } else {
  649. X        iz = ((x->obdub)>(y->obdub));
  650. X    }
  651. X    mfree(x);
  652. X    mfree(y);
  653. X    return torf(iz);
  654. X}
  655. X
  656. Xstruct object *lessp(x,y)    /* lessp */
  657. Xregister struct object *x,*y;
  658. X{
  659. X    int iz;
  660. X
  661. X    x = numconv(x,"Lessp");
  662. X    y = numconv(y,"Lessp");
  663. X    if (!intp(x) || !intp(y)) {
  664. X        x = dubconv(x);
  665. X        y = dubconv(y);
  666. X    }
  667. X    if (intp(x)) {
  668. X        iz = ((x->obint)<(y->obint));
  669. X    } else {
  670. X        iz = ((x->obdub)<(y->obdub));
  671. X    }
  672. X    mfree(x);
  673. X    mfree(y);
  674. X    return torf(iz);
  675. X}
  676. X
  677. Xstruct object *lmax(x,y)    /* maximum */
  678. Xregister struct object *x,*y;
  679. X{
  680. X    x = numconv(x,"Maximum");
  681. X    y = numconv(y,"Maximum");
  682. X    if (!intp(x) || !intp(y)) {
  683. X        x = dubconv(x);
  684. X        y = dubconv(y);
  685. X    }
  686. X    if (intp(x)) {
  687. X        if ((x->obint) > (y->obint)) {
  688. X            mfree(y);
  689. X            return(x);
  690. X        } else {
  691. X            mfree(x);
  692. X            return(y);
  693. X        }
  694. X    } else {
  695. X        if ((x->obdub) > (y->obdub)) {
  696. X            mfree(y);
  697. X            return(x);
  698. X        } else {
  699. X            mfree(x);
  700. X            return(y);
  701. X        }
  702. X    }
  703. X}
  704. X
  705. Xstruct object *lmin(x,y)    /* minimum */
  706. Xregister struct object *x,*y;
  707. X{
  708. X    x = numconv(x,"Minimum");
  709. X    y = numconv(y,"Minimum");
  710. X    if (!intp(x) || !intp(y)) {
  711. X        x = dubconv(x);
  712. X        y = dubconv(y);
  713. X    }
  714. X    if (intp(x)) {
  715. X        if ((x->obint) < (y->obint)) {
  716. X            mfree(y);
  717. X            return(x);
  718. X        } else {
  719. X            mfree(x);
  720. X            return(y);
  721. X        }
  722. X    } else {
  723. X        if ((x->obdub) < (y->obdub)) {
  724. X            mfree(y);
  725. X            return(x);
  726. X        } else {
  727. X            mfree(x);
  728. X            return(y);
  729. X        }
  730. X    }
  731. X}
  732. X
  733. Xstruct object *lnump(x)        /* LOGO numberp */
  734. Xregister struct object *x;
  735. X{
  736. X    if (x == 0) return(false());
  737. X    switch (x->obtype) {
  738. X        case CONS:
  739. X            mfree(x);
  740. X            return(false());
  741. X        case INT:
  742. X        case DUB:
  743. X            mfree(x);
  744. X            return(true());
  745. X        default:    /* case STRING */
  746. X            if (nump(x)) {
  747. X                mfree(x);
  748. X                return(true());
  749. X            } else {
  750. X                mfree(x);
  751. X                return(false());
  752. X            }
  753. X    }
  754. X}
  755. X
  756. Xstruct object *lrandd()        /* random */
  757. X{
  758. X    register struct object *val;
  759. X    register temp;
  760. X
  761. X    temp=(RAND()/100)%10;
  762. X    val = objint((FIXNUM)temp);
  763. X    return(localize(val));
  764. X}
  765. X
  766. Xstruct object *rnd(arg)
  767. Xregister struct object *arg;
  768. X{
  769. X    register temp;
  770. X
  771. X    arg = numconv(arg,"Rnd");
  772. X    if(!intp(arg)) ungood("Rnd",arg);
  773. X    if ((arg->obint) <= 0) ungood("Rnd",arg);
  774. X    temp=RAND() % (int)(arg->obint);
  775. X    mfree(arg);
  776. X    return(localize(objint((FIXNUM)temp)));
  777. X}
  778. X
  779. Xstruct object *sq(arg)
  780. Xregister struct object *arg;
  781. X{
  782. X    NUMBER temp;
  783. X
  784. X    arg = numconv(arg,"Sqrt");
  785. X    arg = dubconv(arg);
  786. X    temp = sqrt(arg->obdub);
  787. X    mfree(arg);
  788. X    return(localize(objdub(temp)));
  789. X}
  790. X
  791. Xstruct object *lsin(arg)
  792. Xregister struct object *arg;
  793. X{
  794. X    NUMBER temp;
  795. X
  796. X    arg = numconv(arg,"Sin");
  797. X    arg = dubconv(arg);
  798. X    temp = sin((3.1415926/180.0)*(arg->obdub));
  799. X    mfree(arg);
  800. X    return(localize(objdub(temp)));
  801. X}
  802. X
  803. Xstruct object *lcos(arg)
  804. Xregister struct object *arg;
  805. X{
  806. X    NUMBER temp;
  807. X
  808. X    arg = numconv(arg,"Cos");
  809. X    arg = dubconv(arg);
  810. X    temp = cos((3.1415926/180.0)*(arg->obdub));
  811. X    mfree(arg);
  812. X    return(localize(objdub(temp)));
  813. X}
  814. X
  815. Xstruct object *lpow(x,y)
  816. Xregister struct object *x,*y;
  817. X{
  818. X    FIXNUM iz;
  819. X    NUMBER dz;
  820. X    register struct object *z;
  821. X
  822. X    x = numconv(x,"Pow");
  823. X    y = numconv(y,"Pow");
  824. X    x = dubconv(x);
  825. X    y = dubconv(y);
  826. X    dz = pow((x->obdub),(y->obdub));
  827. X    iz = dz;    /* convert to integer for integerness test */
  828. X    if (dz == (NUMBER)iz)
  829. X        z = objint(iz);
  830. X    else 
  831. X        z = objdub(dz);
  832. X    mfree(x);
  833. X    mfree(y);
  834. X    return(localize(z));
  835. X}
  836. X
  837. Xstruct object *latan(arg)
  838. Xregister struct object *arg;
  839. X{
  840. X    NUMBER temp;
  841. X
  842. X    arg = numconv(arg,"Atan");
  843. X    arg = dubconv(arg);
  844. X    temp = (180.0/3.1415926)*atan(arg->obdub);
  845. X    mfree(arg);
  846. X    return(localize(objdub(temp)));
  847. X}
  848. X
  849. Xstruct object *zerop(x)        /* zerop */
  850. Xregister struct object *x;
  851. X{
  852. X    register int iz;
  853. X
  854. X    x = numconv(x,"Zerop");
  855. X    if (intp(x))
  856. X        iz = ((x->obint)==0);
  857. X    else
  858. X        iz = ((x->obdub)==0.0);
  859. X    mfree(x);
  860. X    return(torf(iz));
  861. X}
  862. X
  863. Xstruct object *intpart(arg)
  864. Xregister struct object *arg;
  865. X{
  866. X    register FIXNUM result;
  867. X
  868. X    arg = numconv(arg,"Int");
  869. X    if (intp(arg)) return(arg);
  870. X    result = arg->obdub;
  871. X    mfree(arg);
  872. X    return(localize(objint(result)));
  873. X}
  874. X
  875. Xstruct object *round(arg)
  876. Xregister struct object *arg;
  877. X{
  878. X    register FIXNUM result;
  879. X
  880. X    arg = numconv(arg,"Round");
  881. X    if (intp(arg)) return(arg);
  882. X    if (arg->obdub >= 0.0)
  883. X        result = arg->obdub + 0.5;
  884. X    else
  885. X        result = arg->obdub - 0.5;
  886. X    mfree(arg);
  887. X    return(localize(objint(result)));
  888. X}
  889. X
  890. Xstruct object *toascii(arg)
  891. Xregister struct object *arg;
  892. X{
  893. X    register char *cp;
  894. X    char str[50];
  895. X
  896. X    if (arg==0) ungood("Ascii",arg);
  897. X    switch(arg->obtype) {
  898. X        case CONS:
  899. X            ungood("Ascii",arg);
  900. X        case STRING:
  901. X            cp = arg->obstr;
  902. X            break;
  903. X        case INT:
  904. X            sprintf(str,FIXFMT,arg->obint);
  905. X            cp = str;
  906. X            break;
  907. X        case DUB:
  908. X            sprintf(str,"%g",arg->obdub);
  909. X            cp = str;
  910. X            break;
  911. X    }
  912. X    if (strlen(cp) != 1) ungood("Ascii",arg);
  913. X    mfree(arg);
  914. X    return(localize(objint((FIXNUM)((*cp)&0377))));
  915. X}
  916. X
  917. Xstruct object *tochar(arg)
  918. Xregister struct object *arg;
  919. X{
  920. X    register int ichar;
  921. X    char str[2];
  922. X
  923. X    arg = numconv(arg,"Char");
  924. X    if (intp(arg)) ichar = arg->obint;
  925. X    else ichar = arg->obdub;
  926. X    if ((ichar < 0) || (ichar > 255)) ungood("Char",arg);
  927. X    mfree(arg);
  928. X    str[0] = ichar;
  929. X    str[1] = '\0';
  930. X    return(localize(objcpstr(str)));
  931. X}
  932. X
  933. END_OF_logonum.c
  934. if test 9811 -ne `wc -c <logonum.c`; then
  935.     echo shar: \"logonum.c\" unpacked with wrong size!
  936. fi
  937. # end of overwriting check
  938. fi
  939. if test -f logoparse.c -a "${1}" != "-c" ; then 
  940.   echo shar: Will not over-write existing file \"logoparse.c\"
  941. else
  942. echo shar: Extracting \"logoparse.c\" \(4959 characters\)
  943. sed "s/^X//" >logoparse.c <<'END_OF_logoparse.c'
  944. X
  945. X#include "logo.h"
  946. Xextern int multnum,endflag,rendflag,topf;
  947. Xextern char ibuf[];
  948. Xextern char *ibufptr, *getbpt, charib;
  949. Xextern int letflag,pflag;
  950. X#ifdef PAUSE
  951. Xextern int pauselev;
  952. X#endif
  953. Xextern FILE *pbuf;
  954. Xextern struct lexstruct keywords[];
  955. Xextern struct alist *locptr;
  956. Xextern struct runblock *thisrun;
  957. X
  958. Xstruct object *makeword(c)
  959. Xint c;
  960. X{
  961. X    register struct object* obj;
  962. X    register char *s;
  963. X    char str[100];
  964. X
  965. X    s=str;
  966. X    do {
  967. X        if (c == '\\') c = getchar()|0200;
  968. X        else if (c == '%') c = ' '|0200;
  969. X        *s++ = c;
  970. X    } while((c=getchar())>0 && !index(" \t\n[]",c));
  971. X    if (c<=0) {
  972. X        printf("Unmatched [ in procedure.\n");
  973. X        errhand();
  974. X    }
  975. X    charib = c;
  976. X    *s = '\0';
  977. X    obj = objcpstr(str);
  978. X    if (nump(obj)) {
  979. X        obj = numconv(localize(obj),"!makeword");
  980. X        mfree(globcopy(obj));    /* unlocalize */
  981. X        return(obj);
  982. X    }
  983. X    return(globcopy(obj));
  984. X}
  985. X
  986. Xstruct object *makel1()
  987. X{
  988. X    register struct object *head,*tail;
  989. X    register c,cnt;
  990. X
  991. X    while ((c=getchar())==' ' || c=='\t' || c=='\n') ;
  992. X    if(c==']') {
  993. X        charib = c;
  994. X        return ((struct object *)0);
  995. X    }
  996. X    if (c<=0) {
  997. X        printf("Unmatched [ in procedure.\n");
  998. X        errhand();
  999. X    }
  1000. X    head = (struct object*)ckmalloc(sizeof(struct object));
  1001. X    tail = head;
  1002. X    cnt = 0;
  1003. X    head->obtype = CONS;
  1004. X    head->refcnt = 0;
  1005. X    head->obcdr = 0;
  1006. Xloop:
  1007. X    if (c=='[') {
  1008. X        tail->obcar = globcopy(makel1());
  1009. X        getchar();    /* gobble the peeked close bracket */
  1010. X    } else {
  1011. X        tail->obcar = makeword(c);
  1012. X        /* This used to use charib instead of passing the char as
  1013. X         * an argument, but that loses if the first char of a word
  1014. X         * is backslash, in which case something is already in
  1015. X         * charib from getchr1. */
  1016. X    }
  1017. X    while ((c=getchar())==' ' || c=='\t' || c=='\n') ;
  1018. X    if (c==']') {
  1019. X        charib = c;
  1020. X        return (head);
  1021. X    }
  1022. X    if (c<=0) {
  1023. X        printf("Unmatched [ in procedure.\n");
  1024. X        errhand();
  1025. X    }
  1026. X
  1027. X    tail->obcdr = (struct object*)ckmalloc(sizeof(struct object));
  1028. X    tail = tail->obcdr;
  1029. X    tail->obtype = CONS;
  1030. X    tail->refcnt = 1;
  1031. X    tail->obcdr = 0;
  1032. X
  1033. X    goto loop;
  1034. X}
  1035. X
  1036. Xstruct object *makelist()
  1037. X{
  1038. X    return(localize(makel1()));
  1039. X}
  1040. X
  1041. X#ifdef DEBUG
  1042. Xgetchr1()
  1043. X#else
  1044. Xgetchar()
  1045. X#endif
  1046. X{
  1047. X    FAST c;
  1048. X
  1049. X    if (charib) {
  1050. X        c=charib;
  1051. X        charib=0;
  1052. X        return(c);
  1053. X    }
  1054. X    else if (pflag==1) {
  1055. X        while ((c=getc(pbuf))=='\r')
  1056. X            ;
  1057. X        if (c=='\\' && letflag!=1) {    /* continuation line feature */
  1058. X            c=getc(pbuf);
  1059. X            if (c=='\n') c=getc(pbuf);
  1060. X            else {
  1061. X                charib = c;
  1062. X                c = '\\';
  1063. X            }
  1064. X        }
  1065. X        if (!letflag && c>='A' && c<='Z') c+= 32;
  1066. X        return(c);
  1067. X    }
  1068. X    else if (getbpt) {    /* BH 5/19/81 moved down below pflag test */
  1069. X        c = *getbpt++;
  1070. X        if (c) return (c);
  1071. X        if (!thisrun) {
  1072. X            getbpt = 0;
  1073. X            return('\n');
  1074. X        }    /* startup file feature */
  1075. X        --getbpt;
  1076. X        if (--(thisrun->rcount) <= 0) {
  1077. X            if (!rendflag) rendflag = 1;    /* BH 3/17/83 */
  1078. X            return(0);
  1079. X        } else {
  1080. X            rerun();
  1081. X            return('\n');
  1082. X        }
  1083. X    }
  1084. X    else if (ibufptr==NULL) {
  1085. X    rebuff:
  1086. X        if ((c=read(0,ibuf,IBUFSIZ))==IBUFSIZ)
  1087. X            if (ibuf[IBUFSIZ-1]!='\n') {
  1088. X                while (read(0,ibuf,IBUFSIZ)==IBUFSIZ)
  1089. X                    if (ibuf[IBUFSIZ-1]=='\n') break;
  1090. X                puts("Your line is too long.");
  1091. X                errhand();
  1092. X            }
  1093. X        if (c<0) {
  1094. X            /* Error return from read.  Probably signal. */
  1095. X            return ('\n');
  1096. X        }
  1097. X        if (c==0) {
  1098. X            /* Not clear what's right for EOF.  I'd just ignore it
  1099. X               only what if stdin is a file, we'll loop forever.
  1100. X               Compromise: if we're paused, don't lose the valuable
  1101. X               context with a keystroke, otherwise, exit. */
  1102. X#ifdef PAUSE
  1103. X            if (pauselev) return('\n');
  1104. X#endif
  1105. X            leave(3);
  1106. X        }
  1107. X        ibufptr=ibuf;
  1108. X    }
  1109. X    c= *ibufptr++;
  1110. X    if (c=='\\' && letflag!=1) {    /* continuation line feature */
  1111. X        c = *ibufptr++;
  1112. X        if (c=='\n') {
  1113. X            ibufptr=NULL;
  1114. X            goto rebuff;    /* sorry, Jay */
  1115. X        } else {
  1116. X            charib = c;
  1117. X            c = '\\';
  1118. X        }
  1119. X    }
  1120. X    if (!letflag && c>='A' && c<='Z') c+=32;
  1121. X    if (c=='\n') ibufptr=NULL;
  1122. X    return(c);
  1123. X}
  1124. X
  1125. X#ifdef DEBUG
  1126. Xgetchar()
  1127. X{    /* BH 3/23/80 debugging echo output */
  1128. X    register c;
  1129. X
  1130. X    c = getchr1();
  1131. X    if (memtrace) putchar(c);
  1132. X    return(c);
  1133. X}
  1134. X#endif
  1135. X
  1136. Xstruct object *multiop(op,args)
  1137. Xregister op;
  1138. Xregister struct object *args;
  1139. X{
  1140. X    extern struct object *list();
  1141. X
  1142. X    if (keywords[op].lexval==list) return (localize(args));
  1143. X    else if (multnum<2) {
  1144. X        nputs(keywords[op].word);
  1145. X        puts(" needs at least two inputs.");
  1146. X        errhand();
  1147. X    } else if (multnum==2)
  1148. X        return ((*keywords[op].lexval)(localize(args->obcar),
  1149. X              localize(args->obcdr->obcar)));
  1150. X    else {
  1151. X        multnum--;
  1152. X        return ((*keywords[op].lexval)(localize(args->obcar),
  1153. X              multiop(op,args->obcdr)));
  1154. X    }
  1155. X}
  1156. X
  1157. Xstruct object *pots()
  1158. X{
  1159. X    register f;
  1160. X
  1161. X    if (f=fork()) while (wait(0)!=f) ;
  1162. X    else {
  1163. X        execl ("/bin/sh","sh","-c",POTSCMD,0);
  1164. X        exit();
  1165. X    }
  1166. X    return((struct object *)-1);
  1167. X}
  1168. X
  1169. Xlbreak() {
  1170. X#ifdef PAUSE
  1171. X    if (!pflag && thisrun && thisrun->str==(struct object *)(-1))
  1172. X        unpause();
  1173. X#endif
  1174. X    if (!pflag && thisrun) {
  1175. X        rendflag = 1;    /* BH 3/17/83 */
  1176. X        if (thisrun->rprev && !(thisrun->svpflag)) rendflag++;
  1177. X    }
  1178. X}
  1179. X
  1180. Xlstop() {
  1181. X    endflag = 1;
  1182. X#ifdef PAUSE
  1183. X    if (!pflag && thisrun && thisrun->str==(struct object *)(-1))
  1184. X        unpause();
  1185. X#endif
  1186. X    if (!pflag && thisrun) rendflag = 3;    /* BH 3/17/83 */
  1187. X}
  1188. X
  1189. Xltopl() {
  1190. X    topf=1;
  1191. X    errwhere();
  1192. X    errzap();
  1193. X    leave(1);
  1194. X}
  1195. X
  1196. Xlbyecom() {
  1197. X    leave(3);
  1198. X}
  1199. X
  1200. END_OF_logoparse.c
  1201. if test 4959 -ne `wc -c <logoparse.c`; then
  1202.     echo shar: \"logoparse.c\" unpacked with wrong size!
  1203. fi
  1204. # end of overwriting check
  1205. fi
  1206. if test -f olddiff -a "${1}" != "-c" ; then 
  1207.   echo shar: Will not over-write existing file \"olddiff\"
  1208. else
  1209. echo shar: Extracting \"olddiff\" \(6638 characters\)
  1210. sed "s/^X//" >olddiff <<'END_OF_olddiff'
  1211. X
  1212. XA Guide to LSRHS Logo Release 3, for people who knew Release 1
  1213. X
  1214. XLSRHS Logo has been changed to be much faster and more robust.  It also
  1215. Xis different in its user interface from the previous version, so that it
  1216. Xmore closely resembles Apple Logo.  Here are the most important changes:
  1217. X
  1218. X1.  The line number editor no longer exists.  There are two ways to define
  1219. Xa procedure.  The "to" command lets you type in the procedure, somewhat as
  1220. Xbefore, but without line numbers and with no correction facility.  The
  1221. X"edit" command runs edt so you can use the power of display editing.  You
  1222. Xcan use "edit" even if the procedure did not previously exist.
  1223. X
  1224. X2.  Most Logo procedures evaluate their inputs: if you want to use a
  1225. Xparticular word as an input you must quote it.  In old LSRHS Logo there
  1226. Xwere several exceptions: edit, erase, show, and describe all took as inputs
  1227. Xan unquoted name of a procedure.  These procedures are no longer exceptional.
  1228. XYou must say
  1229. X    edit "foo
  1230. Xto edit the procedure foo, for example.  You can also give edit, erase, or
  1231. Xshow a list of procedures as inputs, which will apply them to all of the
  1232. Xprocedures you name at once.  It is particularly convenient sometimes to be
  1233. Xable to edit two procedures at the same time.
  1234. X
  1235. XNote: The "to" command is still exceptional in that it doesn't evaluate
  1236. Xits inputs.
  1237. X
  1238. X3.  The "edit" command with no input at all will re-edit whatever you edited
  1239. Xlast time.  It remembers the buffer file as long as you stay in Logo.
  1240. X
  1241. X4.  If you are editing with "edit" and change your mind, so you don't want to
  1242. Xredefine any procedures, leave edt with ESC ^Z instead of just ^Z.  This will
  1243. Xtell Logo not to change the procedure definitions.  (This is only true at
  1244. XLSRHS, or wherever the text editor cooperates by setting a nonzero exit
  1245. Xstatus.)
  1246. X
  1247. X5.  You can put comments on a Logo instruction line by starting the comment
  1248. Xwith an exclamation point:
  1249. X    print "foo ! This is a comment.
  1250. XThe exclamation point must not be part of a word or list, which is why there
  1251. Xis a space before it in the example.
  1252. X
  1253. X6.  The "if" command syntax is completely different.  It, too, used to be an
  1254. Xexception to the rule about quoting inputs.  It now takes either two or three
  1255. Xinputs.  The first is a predicate, as before.  The second and third are lists
  1256. Xof instructions, as in the repeat command:
  1257. X    if 2=3 [print "yes] [print "no]
  1258. XThe second input is executed if the predicat is true, the (optional) third
  1259. Xif it's false.  If the things in the second and third inputs are expressions
  1260. Xrather than complete instructions, "if" can be used as an operation:
  1261. X    print if 2=3 ["yes] ["no]
  1262. XThe third input is required in that case.
  1263. X
  1264. XThe difference in "if" is likely to be the biggest headache to people used to
  1265. Xthe old way.  Your Logo procedures must be changed like this:
  1266. X    old:    if :num=0 stop
  1267. X    new:    if :num=0 [stop]
  1268. X
  1269. X7.  Many abbreviations are removed or changed:
  1270. X    sentence    s -> se
  1271. X    print        p -> pr
  1272. X    goodbye        g -> bye
  1273. X
  1274. X    gone completely: ei, gp, lp, rq, pro, q, w, eq, ep, np, wp,
  1275. X    c, th, na, lo, m, sp, zp, ti, d, t, ut.
  1276. X
  1277. X8.  Some synonyms are added to be like Apple Logo:
  1278. X    full        fullscreen
  1279. X    split        splitscreen
  1280. X    text        textscreen
  1281. X    atan        arctan
  1282. X    either        or
  1283. X    both        and
  1284. XThe old names still work also.
  1285. X
  1286. X9.  The procedures repeat, nth (synonym item), and memberp, which were
  1287. Xlibrary procedures written in Logo before, are now primitives, so they're
  1288. Xfaster.  NOTE: The order of the inputs to repeat has been reversed:
  1289. X    repeat 4 [fd 40; rt 90]
  1290. X
  1291. X10.  Lots of bugs have been fixed.  In particular, several limitations on
  1292. Xrepeat (and run) have been removed: You can have a repeat within a repeat,
  1293. Xmultiple instructions within a repeat, etc.
  1294. X
  1295. XNew in Release 3 (compared to Release 2):
  1296. X
  1297. X11.  There is now a pause facility, which allows you to enter interactive
  1298. Xcommands in the context of a running procedure, to examine or modify local
  1299. Xvariables.  This happens, among other things, when you type the system
  1300. Xinterrupt character (^C at LSRHS).  Typing the quit character (^G at LSRHS)
  1301. Xdoes what it always did, namely stop all procedures.
  1302. X
  1303. X12.  Turtle commands like forward do an automatic turtle "display if
  1304. Xyou don't already have a turtle.
  1305. X
  1306. X13.  New primitives:
  1307. X
  1308. X(Already in release 2):
  1309. X
  1310. Xreadlist (abbrev rl)--
  1311. X    Like request but doesn't print a "?" prompt.
  1312. X
  1313. Xint--
  1314. X    Takes one numeric input, gives integer part (truncates).
  1315. X
  1316. Xround--
  1317. X    Takes one numeric input, gives nearest integer (rounds).
  1318. X
  1319. Xascii--
  1320. X    Takes a single-character word, gives the numeric code for that char.
  1321. X
  1322. Xchar--
  1323. X    Takes a number, gives the corresponding character.
  1324. X
  1325. Xoflush--
  1326. X    Command, no inputs.  Use this to make stuff you've printed actually
  1327. X    get printed right away.  Normally, what you print is buffered until
  1328. X    you have to type in something.
  1329. X
  1330. Xpprop, gprop, remprop, plist, pps--
  1331. X    Property lists.  Named properties can be associated with a word.
  1332. X    Examples:
  1333. X
  1334. X        pprop "bh "firstname "Brian
  1335. X        pprop "bh "lastname "Harvey
  1336. X        print gprop "bh "firstname
  1337. X            -> Brian
  1338. X        fprint plist "bh
  1339. X            -> [firstname Brian lastname Harvey]
  1340. X        pps
  1341. X            -> bh's firstname is Brian
  1342. X               bh's lastname is Harvey
  1343. X        remprop "bh "lastname
  1344. X
  1345. Xtest, iftrue (abbrev ift), iffalse (abbrev iff)--
  1346. X    An alternate form of "if":
  1347. X
  1348. X        test 2=3
  1349. X        iftrue [print "foo]
  1350. X        iffalse [print "baz]
  1351. X
  1352. X    These are most useful if you have several instructions all conditional
  1353. X    on the same test.  You can use any number of iftrue and iffalse
  1354. X    commands, in any order.  The result of "test" is remembered locally
  1355. X    for each procedure.
  1356. X
  1357. XNew in Release 3 (compared to Release 2):
  1358. X
  1359. Xsetscrunch, scrunch--
  1360. X    Set and get the aspect ratio, a number by which the vertical
  1361. X    component of turtle motion is multiplied.  Make squares really square.
  1362. X
  1363. Xwipeclean (clean)--
  1364. X    Like clearscreen, but don't move the turtle.
  1365. X
  1366. Xpenreverse (px)--
  1367. X    A pen mode in which each dot in the turtle's path is turned on if
  1368. X    it was ff and vice versa.
  1369. X
  1370. Xpenmode--
  1371. X    Outputs one of the words penup, pendown, penerase, or penreverse.
  1372. X
  1373. Xshownp--
  1374. X    Outputs true if the turtle is visible.
  1375. X
  1376. Xtowardsxy--
  1377. X    Outputs the heading to which to turn the turtle in order for it
  1378. X    to face the point specified by the two inputs.
  1379. X
  1380. Xrepcount--
  1381. X    Outputs how many times through the repeat we've done.  Try
  1382. X        repeat 10 [print repcount]
  1383. X        repeat 50 [fd 20+2*repcount; rt 90]
  1384. X
  1385. Xpause--
  1386. X    In a procedure, pause.  Accept commands from the terminal, but with
  1387. X    local variables available.
  1388. X
  1389. Xcontinue (co)--
  1390. X    Continue the procedure from which Logo paused.
  1391. X
  1392. Xerrpause--
  1393. X    From now on, pause instead of stopping if an error happens inside
  1394. X    a procedure.
  1395. X
  1396. Xerrquit--
  1397. X    From now on, quit on errors.
  1398. X
  1399. Xsetipause--
  1400. X    From now on, interrupt (^C) pauses and quit (^G) stops.
  1401. X
  1402. Xsetqpause--
  1403. X    From now on, quit (^G) pauses and interrupt (^C) stops.
  1404. X
  1405. END_OF_olddiff
  1406. if test 6638 -ne `wc -c <olddiff`; then
  1407.     echo shar: \"olddiff\" unpacked with wrong size!
  1408. fi
  1409. # end of overwriting check
  1410. fi
  1411. if test -f procedit.c -a "${1}" != "-c" ; then 
  1412.   echo shar: Will not over-write existing file \"procedit.c\"
  1413. else
  1414. echo shar: Extracting \"procedit.c\" \(6263 characters\)
  1415. sed "s/^X//" >procedit.c <<'END_OF_procedit.c'
  1416. X
  1417. X#include "logo.h"
  1418. X#include <signal.h>
  1419. X
  1420. Xextern int nullfn();
  1421. Xextern int errrec();
  1422. Xextern int ehand2(),ehand3();
  1423. Xextern char *token();
  1424. Xextern char *getenv();
  1425. Xextern char titlebuf[],editfile[];
  1426. Xextern int letflag;
  1427. X#ifndef NOTURTLE
  1428. Xextern int turtdes,textmode;
  1429. Xextern struct display *mydpy;
  1430. X#endif
  1431. X
  1432. Xchkproc(str,prim,obj)
  1433. Xregister char *str;
  1434. Xchar *prim;
  1435. Xstruct object *obj;
  1436. X{
  1437. X    register char ch;
  1438. X
  1439. X    if (((ch = *str)<'a') || (ch>'z')) ungood(prim,obj);
  1440. X    if (memb('/',str)) ungood(prim,obj);
  1441. X    if (strlen(str)>NAMELEN) ungood(prim,obj);
  1442. X}
  1443. X
  1444. Xstedit(ednobj,flag)
  1445. Xstruct object *ednobj;
  1446. Xint flag;
  1447. X{
  1448. X    register char *edname;
  1449. X    register struct object *rest;
  1450. X    char fnam[40];
  1451. X    char edline[100];
  1452. X    FILDES edfd;
  1453. X
  1454. X    if (ednobj==0) ungood("Edit",ednobj);
  1455. X    if (flag==0) unlink(editfile);
  1456. X    switch (ednobj->obtype) {
  1457. X        case INT:
  1458. X        case DUB:
  1459. X            ungood("Edit",ednobj);
  1460. X        case CONS:
  1461. X            for (rest=ednobj; rest; rest=rest->obcdr)
  1462. X                stedit(localize(rest->obcar),1);
  1463. X            break;
  1464. X        default: /* STRING */
  1465. X            edname = token(ednobj->obstr);
  1466. X            chkproc(edname,"Edit",ednobj);
  1467. X            cpystr(fnam,edname,EXTEN,NULL);
  1468. X            if ((edfd=open(fnam,READ,0))<0) {
  1469. X                cpystr(fnam,LIBLOGO,edname,EXTEN,NULL);
  1470. X                if ((edfd=open(fnam,READ,0)) < 0) {
  1471. X                    cpystr(fnam,edname,EXTEN,NULL);
  1472. X                    edfd = creat(fnam,0666);
  1473. X                    if (edfd < 0) {
  1474. X                        printf("Can't write %s.\n",edname);
  1475. X                        mfree(ednobj);
  1476. X                        errhand();
  1477. X                    }
  1478. X                    onintr(ehand3,edfd);
  1479. X                    write(edfd,"to ",3);
  1480. X                    write(edfd,edname,strlen(edname));
  1481. X                    write(edfd,"\n\nend\n",6);
  1482. X                }
  1483. X            }
  1484. X            close(edfd);
  1485. X            onintr(errrec,1);
  1486. X            sprintf(edline,"cat %s >> %s",fnam,editfile);
  1487. X            system(edline);
  1488. X            sprintf(edline,LIBNL,editfile);
  1489. X            system(edline);
  1490. X    }
  1491. X    mfree(ednobj);
  1492. X    if (flag==0) doedit();
  1493. X}
  1494. X
  1495. Xdoedit() {
  1496. X    register char ch,*cp;
  1497. X    FILE *fd,*ofd;
  1498. X    int pid,status;
  1499. X    char *name,*envedit;
  1500. X    char fname[30];
  1501. X    char line[200];
  1502. X    static char binname[25] = "";
  1503. X    static char usrbinname[30];
  1504. X    static char editname[20];
  1505. X    static char *editor;
  1506. X
  1507. X    if (binname[0] == '\0') {
  1508. X        editor = getenv("EDITOR");
  1509. X        envedit = editor ? editor : EDT;    /* default editor */
  1510. X        strcpy(binname,"/bin/");
  1511. X        strcat(binname,envedit);
  1512. X        strcpy(usrbinname,"/usr/bin/");
  1513. X        strcat(usrbinname,envedit);
  1514. X        strcpy(editname,envedit);
  1515. X    }
  1516. X
  1517. X#ifndef NOTURTLE
  1518. X    if (turtdes<0) {
  1519. X        (*mydpy->state)('t');
  1520. X        textmode++;
  1521. X    }
  1522. X#endif
  1523. X    fflush(stdout);
  1524. X    signal(SIGINT,SIG_IGN);
  1525. X    signal(SIGQUIT,SIG_IGN);
  1526. X    switch (pid=fork()) {
  1527. X        case -1:
  1528. X            printf("Can't fork to editor.\n");
  1529. X            errhand();
  1530. X        case 0:
  1531. X            /*if (editor) */ execl(editname,editname,editfile,0);
  1532. X            /* Only try bare name if really user-specified. */
  1533. X            execl(binname,editname,editfile,0);
  1534. X            execl(usrbinname,editname,editfile,0);
  1535. X            printf("Can't find editor.\n");
  1536. X            exit(2);
  1537. X        default:
  1538. X            while (wait(&status) != pid) ;
  1539. X    }
  1540. X    if (status&0177400) {
  1541. X        printf("Redefinition aborted.\n");
  1542. X        errhand();
  1543. X    }
  1544. X    if ((fd=fopen(editfile,"r"))==NULL) {
  1545. X        printf("Can't reread edits!\n");
  1546. X        errhand();
  1547. X    }
  1548. X    onintr(ehand2,fd);
  1549. X    while (fgets(line,200,fd)) {
  1550. X        for (cp = line; (ch = *cp)==' ' || ch=='\t'; cp++) ;
  1551. X        if (ch == '\n') continue;
  1552. X        if (strcmp(token(cp),"to")) {
  1553. X            printf("Edited file includes non-procedure.\n");
  1554. X            ehand2(fd);
  1555. X        }
  1556. X        for (cp += 2; (ch = *cp)==' ' || ch=='\t'; cp++) ;
  1557. X        name = token(cp);
  1558. X        printf("Defining %s\n",name);
  1559. X        sprintf(fname,"%s%s",name,EXTEN);
  1560. X        ofd = fopen(fname,"w");
  1561. X        if (ofd==NULL) {
  1562. X            printf("Can't write %s\n",fname);
  1563. X            ehand2(fd);
  1564. X        }
  1565. X        fprintf(ofd,"%s",line);
  1566. X        while (fgets(line,200,fd)) {
  1567. X            fprintf(ofd,"%s",line);
  1568. X            for (cp = line; (ch = *cp)==' ' || ch=='\t'; cp++) ;
  1569. X            if (!strcmp(token(cp),"end")) break;
  1570. X        }
  1571. X        fclose(ofd);
  1572. X    }
  1573. X    fclose(fd);
  1574. X    onintr(errrec,1);
  1575. X}
  1576. X
  1577. Xstruct object *cmedit(arg)
  1578. Xstruct object *arg;
  1579. X{
  1580. X    stedit(arg,0);
  1581. X    return ((struct object *)(-1));
  1582. X}
  1583. X
  1584. Xstruct object *erase(name)    /* delete a procedure from directory */
  1585. Xregister struct object *name;
  1586. X{
  1587. X    register struct object *rest;
  1588. X    char temp[16];
  1589. X
  1590. X    if (name==0) ungood("Erase",name);
  1591. X    switch(name->obtype) {
  1592. X        case STRING:
  1593. X            cpystr(temp,name->obstr,EXTEN,NULL);
  1594. X            if (unlink(temp)<0) {    /* undefined procedure */
  1595. X                nputs("You haven't defined ");
  1596. X                puts(name->obstr);
  1597. X                errhand();
  1598. X            }
  1599. X            break;
  1600. X        case CONS:
  1601. X            for (rest = name; rest; rest = rest->obcdr)
  1602. X                erase(localize(rest->obcar));
  1603. X            break;
  1604. X        default:    /* number */
  1605. X            ungood("Erase",name);
  1606. X    }
  1607. X    mfree(name);
  1608. X    return ((struct object *)(-1));
  1609. X}
  1610. X
  1611. Xaddlines(edfd)    /* read text of procedure, simple TO style */
  1612. Xint edfd;
  1613. X{
  1614. X    register char *lintem;
  1615. X    int oldlet;
  1616. X    static char tstack[IBUFSIZ];
  1617. X    int brak,brace,ch;    /* BH 1/7/82 */
  1618. X
  1619. X    oldlet=letflag;
  1620. X    letflag=1;    /* read rest of line verbatim */
  1621. Xloop:
  1622. X    putchar('>');
  1623. X    fflush(stdout);
  1624. X    lintem=tstack;
  1625. X    brace = brak = 0;    /* BH 1/7/82 count square brackets */
  1626. X    do {
  1627. X        while ((ch=getchar())!='\n') {
  1628. X            if (lintem >= &tstack[IBUFSIZ-2]) {
  1629. X                printf("Line too long.");
  1630. X                goto loop;
  1631. X            }
  1632. X            *lintem++ = ch;
  1633. X            if (ch == '\\') *lintem++ = getchar();
  1634. X            else if (ch == '[') brak++;
  1635. X            else if (ch == ']') --brak;
  1636. X            else if (brak == 0) {
  1637. X                if (ch == '{' || ch == '(') brace++;
  1638. X                else if (ch == '}' || ch == ')') --brace;
  1639. X            }
  1640. X        }
  1641. X        if (brak > 0) {
  1642. X            *lintem++ = ' ';
  1643. X            printf("[: ");
  1644. X            fflush(stdout);
  1645. X        } else if (brace > 0) {
  1646. X            *lintem++ = ' ';
  1647. X            printf("{(: ");
  1648. X            fflush(stdout);
  1649. X        }
  1650. X    } while (brace+brak > 0);
  1651. X    *lintem++='\n';
  1652. X    *lintem='\0';
  1653. X    write(edfd,tstack,lintem-tstack);
  1654. X    for (lintem = tstack; memb(*lintem++," \t") ; ) ;
  1655. X    --lintem;
  1656. X    if (strcmp(token(lintem),"end")) goto loop;
  1657. X    letflag=oldlet;
  1658. X    close(edfd);
  1659. X}
  1660. X
  1661. Xstruct object *show(nameob)
  1662. Xregister struct object *nameob;
  1663. X{
  1664. X    register struct object *rest;
  1665. X    register char *name;
  1666. X    FILE *sbuf;
  1667. X    char temp[100];
  1668. X
  1669. X    if (nameob==0) ungood("Show",nameob);
  1670. X    switch(nameob->obtype) {
  1671. X        case STRING:
  1672. X            name = nameob->obstr;
  1673. X            cpystr(temp,name,EXTEN,NULL);
  1674. X            if (!(sbuf=fopen(temp,"r"))) {
  1675. X                cpystr(temp,LIBLOGO,name,EXTEN,NULL);
  1676. X                if (!(sbuf = fopen(temp,"r"))) {
  1677. X                    printf("You haven't defined %s\n",name);
  1678. X                    errhand();
  1679. X                }
  1680. X            }
  1681. X            onintr(ehand2,sbuf);
  1682. X            while (putch(getc(sbuf))!=EOF)
  1683. X                ;
  1684. X            fclose(sbuf);
  1685. X            onintr(errrec,1);
  1686. X            break;
  1687. X        case CONS:
  1688. X            for (rest = nameob; rest; rest = rest->obcdr) {
  1689. X                show(localize(rest->obcar));
  1690. X                putchar('\n');
  1691. X            }
  1692. X            break;
  1693. X        default:    /* number */
  1694. X            ungood("Show",nameob);
  1695. X    }
  1696. X    mfree(nameob);
  1697. X    return ((struct object *)(-1));
  1698. X}
  1699. X
  1700. END_OF_procedit.c
  1701. if test 6263 -ne `wc -c <procedit.c`; then
  1702.     echo shar: \"procedit.c\" unpacked with wrong size!
  1703. fi
  1704. # end of overwriting check
  1705. fi
  1706. if test -f procvars.c -a "${1}" != "-c" ; then 
  1707.   echo shar: Will not over-write existing file \"procvars.c\"
  1708. else
  1709. echo shar: Extracting \"procvars.c\" \(7096 characters\)
  1710. sed "s/^X//" >procvars.c <<'END_OF_procvars.c'
  1711. X
  1712. X/*    This file contains stuff about user procedure calls and
  1713. X* variable assignment and lookup.
  1714. X*
  1715. X*    Copyright (C) 1979, The Children's Museum, Boston, Mass.
  1716. X*    Written by Douglas B. Klunder
  1717. X*/
  1718. X
  1719. X#include "logo.h"
  1720. Xextern struct plist *pcell;
  1721. Xextern int *stkbase;
  1722. Xextern int stkbi;
  1723. Xextern int *newstk;
  1724. Xextern int newsti;
  1725. Xextern int argno;
  1726. Xextern int yylval;
  1727. Xextern int yychar;
  1728. Xextern short yyerrflag;
  1729. Xstatic struct alist *globvars;
  1730. Xextern struct stkframe *fbr;
  1731. Xextern struct plist *proclist;
  1732. Xextern struct alist *locptr;
  1733. Xextern struct alist *newloc;
  1734. X
  1735. Xstruct alist *loclk1();
  1736. Xstruct alist *look1();
  1737. Xstruct object *look();
  1738. X
  1739. Xgo(linenum)    /* LOGO go */
  1740. Xregister struct object *linenum;
  1741. X{
  1742. X    register struct lincell *lptr;
  1743. X    register numline;
  1744. X
  1745. X    if (pcell==NULL) {    /* not in procedure */
  1746. X        printf("Go can only be used within a procedure.\n");
  1747. X        errhand();
  1748. X    }
  1749. X    linenum = numconv(linenum,"Go");
  1750. X    if (!intp(linenum)) ungood("Go",linenum);
  1751. X    numline = linenum->obint;
  1752. X    mfree(linenum);
  1753. X/*    Search for saved line no. */
  1754. X    for (lptr=pcell->plines;lptr;lptr=lptr->nextline) {
  1755. X        if (lptr->linenum==numline)
  1756. X        {    /* line found, so adjust pseudo-code
  1757. X            * pointers to continue execution at
  1758. X            * right place
  1759. X            */
  1760. X            stkbase=lptr->base;
  1761. X            stkbi=lptr->index;
  1762. X            return;
  1763. X        }
  1764. X    }
  1765. X    /* no match */
  1766. X    printf("There is no line %d.\n",numline);
  1767. X    errhand();
  1768. X}
  1769. X
  1770. Xchar *lowcase(name)
  1771. Xregister char *name;
  1772. X{
  1773. X    static char result[100];
  1774. X    register char c,*str;
  1775. X
  1776. X    str = result;
  1777. X    while (c = *name++) {
  1778. X        if (c >= 'A' && c <= 'Z') c += 040;
  1779. X        *str++ = c;
  1780. X    }
  1781. X    *str = '\0';
  1782. X    return(result);
  1783. X}
  1784. X
  1785. Xstruct object *lnamep(name)    /* namep */
  1786. Xregister struct object *name;
  1787. X{    /* check for both local and global definitions */
  1788. X    register char *nstr;
  1789. X
  1790. X    if (!stringp(name)) ungood("Namep",name);
  1791. X    nstr = lowcase(name->obstr);
  1792. X    if (loclk1(nstr) || look1(nstr)) {
  1793. X        mfree(name);
  1794. X        return(true());
  1795. X    }
  1796. X    mfree(name);
  1797. X    return(false());
  1798. X}
  1799. X
  1800. Xloccreate(varname,lptr)        /* create new local variable cell, with name
  1801. X                * but without value */
  1802. Xregister struct object *varname;
  1803. Xregister struct alist **lptr;
  1804. X{
  1805. X    register struct alist *temp1,*temp2;
  1806. X    char ch,*str;
  1807. X
  1808. X    if (pcell==NULL) {    /* not in procedure */
  1809. X        printf("Local can only be used within a procedure.\n");
  1810. X        errhand();
  1811. X    }
  1812. X    if (!stringp(varname)) ungood("Local",varname);
  1813. X    str = lowcase(varname->obstr);
  1814. X    if ((ch = str[0]) == '\0') {
  1815. X        printf("Variable name can't be empty.\n");
  1816. X        errhand();
  1817. X    }
  1818. X    if (ch<'a' || ch>'z') {
  1819. X        printf("Variable name %s must start with a letter.\n",
  1820. X                varname->obstr);
  1821. X        errhand();
  1822. X    }
  1823. X    if (*lptr==NULL) {    /* first cell */
  1824. X        *lptr=(temp1=(struct alist *)ckzmalloc(sizeof(*temp1)));
  1825. X    } else {
  1826. X        for (temp1= *lptr;temp1;temp1=temp1->next) {
  1827. X            if (!strcmp(temp1->name->obstr,str))
  1828. X            {    /* name already present */
  1829. X                nputs(varname->obstr);
  1830. X                printf(" is already defined as a local variable.\n");
  1831. X                errhand();
  1832. X            }
  1833. X            temp2=temp1;
  1834. X        }
  1835. X        /* create new cell at end of string */
  1836. X        temp2->next=(struct alist *)ckzmalloc(sizeof(*temp2));
  1837. X        temp1=temp2->next;
  1838. X    }
  1839. X    temp1->next=NULL;
  1840. X    temp1->name=globcopy(objcpstr(str));
  1841. X    temp1->val=(struct object *)-1;
  1842. X    lfree(varname);
  1843. X}
  1844. X
  1845. Xstruct object *cmlocal(arg)
  1846. Xstruct object *arg;
  1847. X{
  1848. X    loccreate(globcopy(arg),&locptr);
  1849. X    mfree(arg);
  1850. X    return ((struct object *)(-1));
  1851. X}
  1852. X
  1853. Xstruct alist *loclk2(str,lap)    /* look for local definition of variable
  1854. X                * return cell pointer if found */
  1855. X        /* BH 5/19/81 was loclk1 but now subprocedure */
  1856. Xregister char *str;
  1857. Xregister struct alist *lap;
  1858. X{
  1859. X    while (lap) {
  1860. X        if (!strcmp(str,lap->name->obstr)) return(lap);
  1861. X        lap=lap->next;
  1862. X    }
  1863. X    return(NULL);
  1864. X}
  1865. X
  1866. Xstruct alist *loclk1(str)    /* look for local definition of variable
  1867. X                 * WITH DYNAMIC SCOPE!! BH 5/19/81 */
  1868. Xregister char *str;
  1869. X{
  1870. X    register struct stkframe *skp;
  1871. X    register struct alist *lap;
  1872. X
  1873. X    if (lap = loclk2(str,locptr)) return(lap);
  1874. X        /* found in innermost active procedure */
  1875. X    for (skp = fbr; skp; skp = skp->prevframe) {
  1876. X        /* else try other active procedures */
  1877. X        if (skp->loclist)
  1878. X            if ((lap = loclk2(str,skp->loclist)) != NULL)
  1879. X                return(lap);
  1880. X    }
  1881. X    return(NULL);
  1882. X}
  1883. X
  1884. Xstruct object *alllk(str)    /* return value of variable */
  1885. Xregister struct object *str;
  1886. X{    /* look both locally and globally */
  1887. X    register struct alist *ap;
  1888. X    register char *strnm;
  1889. X
  1890. X    if (!stringp(str)) ungood("Thing",str);
  1891. X    strnm = lowcase(str->obstr);
  1892. X    if ((ap=loclk1(strnm))==NULL) return(look(str));
  1893. X    if (ap->val==(struct object *)-1) {
  1894. X        nputs(strnm);
  1895. X        puts(" has no value.");
  1896. X        errhand();
  1897. X    }
  1898. X    mfree(str);
  1899. X    return(localize(ap->val));
  1900. X}
  1901. X
  1902. Xnewfr()        /* create new stack frame to accommodate procedure */
  1903. X{
  1904. X    register int *temp;
  1905. X
  1906. X    temp=(int *)ckmalloc(PSTKSIZ*sizeof(int));
  1907. X    *temp=(int)newstk;
  1908. X    *(newstk+PSTKSIZ-1)=(int)temp;
  1909. X    newstk=temp;
  1910. X    newsti=1;
  1911. X}
  1912. X
  1913. Xstruct plist *proclook(name)    /* check if procedure already in memory */
  1914. Xregister char *name;
  1915. X{
  1916. X    register struct plist *here;
  1917. X
  1918. X    for (here=proclist;here;here=here->after)
  1919. X        if (!strcmp(name,here->procname->obstr)) return(here);
  1920. X    return(NULL);
  1921. X}
  1922. X
  1923. Xargassign(argval)    /* assign value to next unfilled input */
  1924. Xregister struct object *argval;
  1925. X{
  1926. X    register struct alist *temp1;
  1927. X
  1928. X    for (temp1=newloc;temp1->val!=(struct object *)-1;temp1=temp1->next) {
  1929. X        if (!stringp(temp1->name)) {
  1930. X            printf("Argassign bug trap, newloc messed up.\n");
  1931. X            return;
  1932. X        }
  1933. X    }
  1934. X    temp1->val=globcopy(argval);
  1935. X    mfree(argval);
  1936. X    if (--argno==0) {    /* all inputs filled, so save unparsed token */
  1937. X        fbr->oldyyl=yylval;
  1938. X        fbr->oldyyc=yychar;
  1939. X        if (yyerrflag) return;
  1940. X        yychar= -1;
  1941. X    }
  1942. X}
  1943. X
  1944. Xassign(name,val)    /* make */
  1945. Xregister struct object *name,*val;
  1946. X{
  1947. X    register struct alist *ap;
  1948. X    register char *namestr;
  1949. X    char *tmp,ch;
  1950. X
  1951. X    if (!stringp(name)) ungood("Make",name);
  1952. X    namestr = lowcase(name->obstr);
  1953. X    for(tmp=namestr;*tmp;tmp++){
  1954. X        if((*tmp<'a' || *tmp>'z') && (*tmp <'0' || *tmp>'9')
  1955. X                && (*tmp != '.') && (*tmp != '_')) {
  1956. X            pf1("Cannot assign value to %l\n",name);
  1957. X            errhand();
  1958. X        }
  1959. X    }
  1960. X    if ((ap=loclk1(namestr))) {    /* local definition */
  1961. X        if (ap->val != (struct object *)-1) lfree(ap->val);
  1962. X        mfree(name);
  1963. X        ap->val=globcopy(val);
  1964. X        mfree(val);
  1965. X        return;
  1966. X    }
  1967. X    else if ((ap=look1(namestr))==0)
  1968. X    {    /* new variable, so allocate cell */
  1969. X        if ((ch = namestr[0]) == '\0') {
  1970. X            printf("Variable name can't be empty.\n");
  1971. X            errhand();
  1972. X        }
  1973. X        if (ch<'a' || ch>'z') {
  1974. X            printf("Variable name %s must start with a letter.\n",
  1975. X                    namestr);
  1976. X            errhand();
  1977. X        }
  1978. X        ap=(struct alist *)ckmalloc(sizeof(*ap));
  1979. X        ap->name = globcopy(objcpstr(namestr));
  1980. X        ap->next=globvars;
  1981. X        globvars=ap;
  1982. X        mfree(name);
  1983. X    } else {    /* old global definition */
  1984. X        lfree(ap->val);
  1985. X        mfree(name);
  1986. X    }
  1987. X    ap->val=globcopy(val);
  1988. X    mfree(val);
  1989. X}
  1990. X
  1991. Xstruct object *look(str)    /* return value of globally defined variable */
  1992. Xregister struct object *str;
  1993. X{
  1994. X    register struct alist *ap;
  1995. X    register char *strtxt;
  1996. X
  1997. X    if (!stringp(str)) ungood("Thing",str);
  1998. X    strtxt = lowcase(str->obstr);
  1999. X    ap=look1(strtxt);
  2000. X    if (ap==NULL) {
  2001. X        nputs(strtxt);
  2002. X        printf(" has no value.\n");
  2003. X        errhand();
  2004. X    }
  2005. X    mfree(str);
  2006. X    return(localize(ap->val));
  2007. X}
  2008. X
  2009. Xstruct alist *look1(str)    /* return pointer to right variable cell */
  2010. Xregister char *str;
  2011. X{
  2012. X    register struct alist *ap;
  2013. X
  2014. X    for(ap=globvars; ap != 0; ap=ap->next)
  2015. X        if (!strcmp(str,ap->name->obstr)) return(ap);
  2016. X    return(0);
  2017. X}
  2018. X
  2019. END_OF_procvars.c
  2020. if test 7096 -ne `wc -c <procvars.c`; then
  2021.     echo shar: \"procvars.c\" unpacked with wrong size!
  2022. fi
  2023. # end of overwriting check
  2024. fi
  2025. if test -f storage.c -a "${1}" != "-c" ; then 
  2026.   echo shar: Will not over-write existing file \"storage.c\"
  2027. else
  2028. echo shar: Extracting \"storage.c\" \(4825 characters\)
  2029. sed "s/^X//" >storage.c <<'END_OF_storage.c'
  2030. X
  2031. X#include "logo.h"
  2032. X
  2033. Xextern struct object *allocstk[];
  2034. X
  2035. Xchar *ckmalloc(size)
  2036. Xint size;
  2037. X{
  2038. X    register char *block;
  2039. X    extern char *malloc();
  2040. X
  2041. X    block = malloc(size);
  2042. X    if (block==0) {
  2043. X        printf("No more memory, sorry.\n");
  2044. X        errhand();
  2045. X    }
  2046. X#ifdef DEBUG
  2047. X    if (memtrace) {
  2048. X        printf("Malloc size=%d loc=0%o\n",size,block);
  2049. X    }
  2050. X#endif
  2051. X    return(block);
  2052. X}
  2053. X
  2054. Xchar *ckzmalloc(size)
  2055. Xint size;
  2056. X{
  2057. X    register char *block;
  2058. X    register int *ip;
  2059. X
  2060. X    block = ckmalloc(size);
  2061. X    for (ip = (int *)block; (char *)ip < block+size; )
  2062. X        *ip++ = 0;
  2063. X    return(block);
  2064. X}
  2065. X
  2066. Xmfree(ptr)    /* free allocated space, allowing another chunk to be */
  2067. Xregister struct object *ptr;
  2068. X{
  2069. X    register struct object **i;
  2070. X
  2071. X#ifdef DEBUG
  2072. X    if(ptr==(struct object *)-1) {
  2073. X        puts("mfree of -1");
  2074. X        return;
  2075. X    }    /* BH 3/5/80 bug trap */
  2076. X#endif
  2077. X    if (ptr==0) return; /* BH 3/5/80 this is ok */
  2078. X    for (i = allocstk; i < &allocstk[MAXALLOC]; i++)
  2079. X        if (*i == ptr) break;
  2080. X#ifdef DEBUG
  2081. X    if (*i != ptr) {
  2082. X        pf1("Trying to mfree nonlocal at 0%o val=%p\n",ptr,ptr);
  2083. X        return;
  2084. X    }
  2085. X    if (memtrace)
  2086. X        pf1("\nMfree entry=%d loc=0%o val=%p\n",i,ptr,ptr);
  2087. X#endif
  2088. X    *i = 0;
  2089. X    lfree(ptr);
  2090. X}
  2091. X
  2092. Xlfree(ptr)
  2093. Xregister struct object *ptr;
  2094. X{
  2095. X#ifdef DEBUG
  2096. X    if(ptr== (struct object *)-1){
  2097. X        puts("lfree of -1");
  2098. X        return;
  2099. X    }
  2100. X#endif
  2101. X    if(ptr==0) return;
  2102. X    if (--(ptr->refcnt) > 0) return;
  2103. X#ifdef DEBUG
  2104. X    if ((ptr->refcnt) < 0) {
  2105. X        printf("Trying to lfree negative refcnt, loc=0%o\n",
  2106. X                ptr);
  2107. X        return;
  2108. X    }
  2109. X    if (memtrace) {
  2110. X        (ptr->refcnt)++;
  2111. X        pf1("\nLfree loc=0%o val=%p\n",ptr,ptr);
  2112. X        (ptr->refcnt)--;
  2113. X    }
  2114. X#endif
  2115. X    if (listp(ptr)) {
  2116. X        lfree(ptr->obcar);
  2117. X        lfree(ptr->obcdr);
  2118. X    }
  2119. X    if (stringp(ptr)) {
  2120. X#ifdef DEBUG
  2121. X        if (memtrace)
  2122. X            printf("Lfree frees string %s at 0%o\n",
  2123. X                    ptr->obstr,ptr->obstr);
  2124. X#endif
  2125. X        free(ptr->obstr);
  2126. X    }
  2127. X    free(ptr);
  2128. X}
  2129. X
  2130. X#ifdef SMALL
  2131. X/* In small Logo, refcnts are chars.  Make an actual copy for things with
  2132. X * lots of references, which should be rare. */
  2133. Xstruct object *realcopy(old)
  2134. Xregister struct object *old;
  2135. X{
  2136. X    register struct object *new;
  2137. X
  2138. X    new = (struct object *)ckmalloc(sizeof(struct object));
  2139. X    new->obtype = old->obtype;
  2140. X    new->refcnt = 0;
  2141. X    switch (new->obtype) {
  2142. X        case CONS:
  2143. X            new->obcar = globcopy(old->obcar);
  2144. X            new->obcdr = globcopy(old->obcdr);
  2145. X            break;
  2146. X        case INT:
  2147. X            new->obint = old->obint;
  2148. X            break;
  2149. X        case DUB:
  2150. X            new->obdub = old->obdub;
  2151. X            break;
  2152. X        default:    /* STRING */
  2153. X            new->obstr = ckmalloc(1+strlen(old->obstr));
  2154. X            strcpy(new->obstr,old->obstr);
  2155. X    }
  2156. X    return(new);
  2157. X}
  2158. X#endif
  2159. X
  2160. Xstruct object *localize(new)
  2161. Xregister struct object *new;
  2162. X{
  2163. X    register struct object **i;
  2164. X
  2165. X    if (new==0) return(0);
  2166. X    for (i = allocstk; i < &allocstk[MAXALLOC]; i++)
  2167. X        if (*i == 0) break;
  2168. X    if (*i != 0) {
  2169. X        puts("I can't remember everything you have told me.");
  2170. X        puts("Please enter less complex instructions.");
  2171. X        errhand();
  2172. X    }
  2173. X#ifdef SMALL
  2174. X    if (new->refcnt == 127) new = realcopy(new);
  2175. X#endif SMALL
  2176. X    *i = new;
  2177. X    new->refcnt++;
  2178. X    return(new);
  2179. X}
  2180. X
  2181. Xstruct object *globcopy(obj)
  2182. Xregister struct object *obj;
  2183. X{
  2184. X    if (obj==0) return(0);
  2185. X#ifdef SMALL
  2186. X    if (obj->refcnt == 127) obj = realcopy(obj);
  2187. X#endif SMALL
  2188. X    obj->refcnt++;
  2189. X    return(obj);
  2190. X}
  2191. X
  2192. Xstruct object *globcons(first,rest)
  2193. Xregister struct object *first,*rest;
  2194. X{
  2195. X    register struct object *new;
  2196. X
  2197. X    new = (struct object *)ckmalloc(sizeof(struct object));
  2198. X    new->obtype = CONS;
  2199. X    new->refcnt = 0;
  2200. X    new->obcar = globcopy(first);
  2201. X    new->obcdr = globcopy(rest);
  2202. X    return(new);
  2203. X}
  2204. X
  2205. Xstruct object *loccons(first,rest)
  2206. Xstruct object *first,*rest;
  2207. X{
  2208. X    return(localize(globcons(first,rest)));
  2209. X}
  2210. X
  2211. Xstruct object *objstr(string)
  2212. Xregister char *string;
  2213. X{
  2214. X    register struct object *new;
  2215. X
  2216. X    new = (struct object *)ckmalloc(sizeof(struct object));
  2217. X    new->obtype = STRING;
  2218. X    new->refcnt = 0;
  2219. X    new->obstr = string;
  2220. X    return(new);
  2221. X}
  2222. X
  2223. Xstruct object *objcpstr(string)
  2224. Xregister char *string;
  2225. X{
  2226. X    register struct object *new;
  2227. X    register char *newstr;
  2228. X
  2229. X    newstr = ckmalloc(strlen(string)+1);
  2230. X    strcpy(newstr,string);
  2231. X    new = (struct object *)ckmalloc(sizeof(struct object));
  2232. X    new->obtype = STRING;
  2233. X    new->refcnt = 0;
  2234. X    new->obstr = newstr;
  2235. X    return(new);
  2236. X}
  2237. X
  2238. Xstruct object *objint(num)
  2239. XFIXNUM num;
  2240. X{
  2241. X    register struct object *new;
  2242. X
  2243. X    new = (struct object *)ckmalloc(sizeof(struct object));
  2244. X    new->obtype = INT;
  2245. X    new->refcnt = 0;
  2246. X    new->obint = num;
  2247. X    return(new);
  2248. X}
  2249. X
  2250. Xstruct object *objdub(num)
  2251. XNUMBER num;
  2252. X{
  2253. X    register struct object *new;
  2254. X
  2255. X    new = (struct object *)ckmalloc(sizeof(struct object));
  2256. X    new->obtype = DUB;
  2257. X    new->refcnt = 0;
  2258. X    new->obdub = num;
  2259. X    return(new);
  2260. X}
  2261. X
  2262. Xstruct object *bigsave(string)
  2263. Xregister char *string;
  2264. X/* used by stringform to get an extra null at the end, kludge */
  2265. X/* Note -- returned object is localized! */
  2266. X{
  2267. X    register char *newstr;
  2268. X    register struct object *newobj;
  2269. X
  2270. X    newstr = ckmalloc(2+strlen(string));
  2271. X    strcpy(newstr,string);
  2272. X    newobj = (struct object *)ckmalloc(sizeof(struct object));
  2273. X    newobj->obtype = STRING;
  2274. X    newobj->refcnt = 0;
  2275. X    newobj->obstr = newstr;
  2276. X    return(localize(newobj));
  2277. X}
  2278. X
  2279. END_OF_storage.c
  2280. if test 4825 -ne `wc -c <storage.c`; then
  2281.     echo shar: \"storage.c\" unpacked with wrong size!
  2282. fi
  2283. # end of overwriting check
  2284. fi
  2285. echo shar: End of archive 2 \(of 6\).
  2286. cp /dev/null ark2isdone
  2287. MISSING=""
  2288. for I in 1 2 3 4 5 6 ; do
  2289.     if test ! -f ark${I}isdone ; then
  2290.     MISSING="${MISSING} ${I}"
  2291.     fi
  2292. done
  2293. if test "${MISSING}" = "" ; then
  2294.     echo You have unpacked all 6 archives.
  2295.     echo "Now see the README"
  2296.     rm -f ark[1-9]isdone
  2297. else
  2298.     echo You still need to unpack the following archives:
  2299.     echo "        " ${MISSING}
  2300. fi
  2301. ##  End of shell archive.
  2302. exit 0
  2303.